package metamodel.coreservices;

import metamodel.transformer.TopDownTransformingGraphTraverser;
import metamodel.transformer.TopDownGraphTransformer;
import metamodel.*;

import java.util.Collection;
import java.util.List;

/**
 * User: felix
 * Date: 10.06.2005
 */
public class SimpleComparator implements TopDownGraphTransformer {
    private static class ComparatorException extends RuntimeException{
        public ComparatorException() {
        }

        public ComparatorException(String message) {
            super(message);
        }

    }

    ClassNode metaInfo;

    public SimpleComparator(ClassNode metaInfo) {
        this.metaInfo = metaInfo;
    }

    public boolean equals(Object o1, Object o2){
        TopDownTransformingGraphTraverser iter = new TopDownTransformingGraphTraverser(metaInfo, this, true);
        try{
        iter.iterate(o1,o2);
        }catch (ComparatorException e){
            return false;
        }
        return true;

    }

    public Object visitRecord(ClassNode classNode, Object data, Object parent) {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public void visitFlatProperty(FlatProperty p, Object value, Object parent) {
        if (!value.equals(p.getValue(parent)))
            throw new ComparatorException();
    }

    public Object visitObjectReference(ObjectReference objectReference, Object value, Object parent) {
        return objectReference.getValue(parent);
    }

    public Collection visitCollection(CollectionRef collectionRef, Collection value, Object parent) {

        final Collection otherCollection = (Collection) collectionRef.getValue(parent);
        if (value.size()!=otherCollection.size())
                throw new ComparatorException();
        return otherCollection;
    }

    public void  visitCyclic(Property p, Object enclosing, Object parent) {
        if (!p.getValue(enclosing).equals(p.getValue(parent))){
            throw new ComparatorException();
        }

    }

    public Object visitCollectionElement(CollectionRef collectionRef, int i,Object value, Collection parent) {
        return ((List)parent).get(i);
    }
}
